#![cfg_attr(all(not(debug_assertions)), windows_subsystem = "windows")]
// Forbid warnings in release builds:
#![cfg_attr(not(debug_assertions), deny(warnings))]
// #![forbid(unsafe_code)]

mod chess;
mod gui;

pub use chess::*;
use std::path::PathBuf;

fn main() {
    let args: Vec<String> = std::env::args().collect();
    let book_file = if args.len() >= 2 {
        Some(PathBuf::from(&args[1]))
    } else {
        None
    };
    let book = if let Some(file) = book_file.as_ref() {
        Book::load_from_text(file).expect("load book file")
    } else {
        Book::new("象棋打谱".to_string())
    };
    if args.len() == 4 && args[2] == "search" {
        let pattern = args[3]
            .split(' ')
            .map(|item| {
                let piece = Piece::from_char(item.as_bytes()[0]).expect("piece char");
                let pos = Pos(std::str::from_utf8(&item.as_bytes()[1..])
                    .expect("utf8 chars")
                    .parse::<u8>()
                    .expect("pos number"));
                (piece, pos)
            })
            .collect::<Vec<_>>();
        let result = book.search_situation(&pattern);
        if result.len() > 0 {
            for situation in result {
                println!(
                    "{} {}",
                    situation.id,
                    std::str::from_utf8(&situation.pieces).unwrap()
                );
            }
        } else {
            println!("未找到匹配的局面");
        }
        return;
    }
    let start = if args.len() >= 3 {
        Some(args[2].parse::<SituationId>().expect("Situation Id"))
    } else {
        None
    };
    let turn = if args.len() >= 4 {
        Color::from_char(args[3].as_bytes()[0])
    } else {
        None
    };
    let app_name = book.name.clone();
    let mut app = gui::EditorApp::new(book, book_file, start, turn);
    let mut native_options = eframe::NativeOptions::default();
    native_options.maximized = true;
    native_options.default_theme = eframe::Theme::Light;

    eframe::run_native(
        app_name.as_str(),
        native_options,
        Box::new(|cc| {
            app.setup(&cc.egui_ctx);
            Box::new(app)
        }),
    )
    .unwrap_or_else(|err| {
        crate::gui::show_error_message("Error", &err.to_string());
    });
}
